package com.spring.trade.service.impl;

import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.internal.util.AlipaySignature;
import com.spring.common.ossClinet.BeanToMapUtil;
import com.spring.common.redis.JedisManager;
import com.spring.doctor.dto.DoctorDto;
import com.spring.doctor.service.IDocDoctorInfoService;
import com.spring.patient.po.PatientCustomer;
import com.spring.pay.alipay.config.AlipayConfig;
import com.spring.pay.alipay.service.IAlipayService;
import com.spring.pay.alipay.vo.AlipayBizContentVo;
import com.spring.pay.alipay.vo.AlipayOrderInfoVo;
import com.spring.pay.cmb.config.CmbConfig;
import com.spring.pay.cmb.service.ICmbpayService;
import com.spring.pay.cmb.util.SubStringUtil;
import com.spring.pay.cmb.vo.CmbPrePayVo;
import com.spring.pay.weixin.config.WeiXinConfig;
import com.spring.pay.weixin.handler.PrepayIdRequestHandler;
import com.spring.pay.weixin.service.IWeiXinService;
import com.spring.pay.weixin.util.MD5Util;
import com.spring.pay.weixin.util.WXUtil;
import com.spring.pay.weixin.util.XMLUtil;
import com.spring.pay.weixin.vo.WeiXinOrderInfoVo;
import com.spring.trade.dao.TradeOrderInfoDao;
import com.spring.trade.dto.PatientTradeOrderDto;
import com.spring.trade.dto.TradeInComeDto;
import com.spring.trade.dto.TradeOrderDto;
import com.spring.trade.dto.TradeOrderInfoDto;
import com.spring.trade.dto.TradeServiceDto;
import com.spring.trade.po.TradeOrderInfo;
import com.spring.trade.service.ITradeOrderInfoService;
import com.spring.trade.vo.TradeOrderInfoVo;
import com.spring.util.AliSmsService;
import com.spring.util.DateUtil;
import com.spring.util.DateUtils;
import com.spring.util.IdentityHelper;
import com.spring.util.StringUtil;
import com.spring.util.TradeOrderInfoStatus;
import com.spring.util.constant.Constant;

import cmb.MerchantCode;

@Service
public class TradeOrderInfoServiceImpl implements ITradeOrderInfoService {
	private Logger LOGGER = Logger.getLogger(TradeOrderInfoServiceImpl.class);


	@Autowired
	private TradeOrderInfoDao tradeOrderInfoDao;
	@Autowired
	private IDocDoctorInfoService doctorInfoService;
/*	@Autowired
	private ITradeServiceInfoService tradeServiceInfoService;

	@Autowired
	private IPatientCustomerService patientCustomerService;*/

	@Autowired
	private ICmbpayService cmbpayService;

	@Autowired
	private IWeiXinService weiXinService;

	@Autowired
	private IAlipayService alipayService;


	@Override
	public List<TradeInComeDto> getIncomeList(Long docId) {
		return tradeOrderInfoDao.find("getIncomeList", docId);
	}

	@Override
	public List<TradeServiceDto> getServiceDtoList(Long patientId, String serviceType,Integer record) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("patientId", patientId);
		map.put("record", record);
		if (serviceType.equals("0")) {
			return tradeOrderInfoDao.find("getCurrentServiceList", map);
		} else {
			return tradeOrderInfoDao.find("getAllServiceList", map);
		}
	}

	@Override
	public List<TradeOrderDto> getOrderList(Long patiendId) {
		return tradeOrderInfoDao.find("getOrderList", patiendId);
	}

	@Override
	public TradeOrderInfoDto getOrderInfo(String orderNo) {
		return tradeOrderInfoDao.get("getOrderInfo", orderNo);
	}

	@Override
	public TradeOrderInfoDto getOrderInfoAndRule(String orderNo, String ruleCode) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orderNo", orderNo);
		map.put("ruleCode", ruleCode);
		return tradeOrderInfoDao.get("getOrderInfoAndRule", map);
	}

	@Override
	public int updateSendNumByOrderNo(String orderNo) {
		return tradeOrderInfoDao.updateByObject("updateByOrderNo", orderNo);
	}

	@Override
	public void procExpiredOrders() {
		tradeOrderInfoDao.updateByObject("checkAndCloseExpiredOrders", null);
	}

	@Override
	public List<TradeOrderInfoDto> getExpireOrderAndNoReplyList() {
		return tradeOrderInfoDao.find("getExpireOrderAndNoReplyList", null);
	}



	@Override
	public List<TradeOrderInfoDto> getCompleteOrderList() {
		return tradeOrderInfoDao.find("getCompleteOrderList", null);
	}

	@Override
	public void updateOrderStatus() throws Exception {

	}

	@Override
	public void updateExpiredOrderStatusAndEndTime() throws Exception {
		
	}

	/**
	 * 待退款发送短信
	 * 
	 * @param tradeOrder
	 * @throws Exception
	 */
	public void stayRefundSendSms(TradeOrderInfoDto tradeOrder) throws Exception {
		
	}

	@Override
	public Object createDocSerOrder(TradeOrderInfo orderInfo, HttpServletRequest request) throws Exception {

		orderInfo.setOrderNo(IdentityHelper.SerializeNo());
		if (orderInfo.getOrderMoney().compareTo(new BigDecimal(0)) == 0) { // 金额为零直接创建一个已支付的订单
			orderInfo.setStatus(TradeOrderInfoStatus.ORDER_PAY.getValue());
			orderInfo.setPayTime(new Date());
			orderInfo.setRecordNum(0);
			tradeOrderInfoDao.insert(orderInfo);
			TradeOrderInfoDto infoDto = getOrderInfoByPidAndDid(orderInfo.getDoctorId(), orderInfo.getPatientId());
			return infoDto;
		}
		// 查询用户是否有未支付的订单，如果有，就把订单信息和支付签名给返回
		TradeOrderInfo orderInfoTemp = getPatientNoPayOrder(orderInfo.getPatientId(), orderInfo.getDoctorId(),orderInfo.getServiceType());
		if (orderInfoTemp == null) {
			orderInfo.setStatus(TradeOrderInfoStatus.ORDER_NOT_PAY.getValue());
			orderInfo.setRecordNum(0);
			tradeOrderInfoDao.insert(orderInfo);
		} else { // 将之前创建的订单号给新的数据
			orderInfo.setOrderNo(orderInfoTemp.getOrderNo());
		}
		if (Constant.alipay.equals(orderInfo.getPayType())) {
			return getAliPaySinInfo(request, orderInfo);
		}
		return null;
	}

	@Override
	public Object createTradeOrder(TradeOrderInfo orderInfo, HttpServletRequest request) throws Exception {

		//支付类型通过参数传递过来的
		orderInfo.setOrderNo(IdentityHelper.SerializeNo());
		int serviceType = orderInfo.getServiceType();
		if (orderInfo.getOrderMoney().compareTo(new BigDecimal(0)) == 0) { // 金额为零直接创建一个已支付的订单
			orderInfo.setStatus(TradeOrderInfoStatus.ORDER_PAY.getValue());
			orderInfo.setPayTime(new Date());
			orderInfo.setRecordNum(0);
			tradeOrderInfoDao.insert(orderInfo);
			TradeOrderInfoDto infoDto = getOrderInfo(orderInfo.getOrderNo());
			if (serviceType == 2) {
				// 将订单号更新到call_patient_info表中
		//		patientBuyCallService.updateCallPatientOrderNo(orderInfo.getCallPatientId(), orderInfo.getOrderNo());
			}
		//	doctorInfoService.updateActiveTime(orderInfo.getDoctorId());
			return infoDto;
		}
		//查询用户是否有未支付的订单，如果有，就把订单信息和支付签名给返回
		if (serviceType == 1){
			TradeOrderInfo orderInfoTemp = getPatientNoPayOrder(orderInfo.getPatientId(),orderInfo.getDoctorId(),serviceType);
			if (orderInfoTemp == null) {
				//金额不为零，创建一个未支付的订单
				orderInfo.setStatus(TradeOrderInfoStatus.ORDER_NOT_PAY.getValue());
				orderInfo.setRecordNum(0);
				tradeOrderInfoDao.insert(orderInfo);
			}else{ //将之前创建的订单号给新的数据
				orderInfo.setOrderNo(orderInfoTemp.getOrderNo());
			}
		}else if (serviceType == 2){
			orderInfo.setStatus(TradeOrderInfoStatus.ORDER_NOT_PAY.getValue());
			orderInfo.setRecordNum(0);
			tradeOrderInfoDao.insert(orderInfo);
			if (serviceType == 2) {
				// 将订单号更新到call_patient_info表中
//				patientBuyCallService.updateCallPatientOrderNo(orderInfo.getCallPatientId(), orderInfo.getOrderNo());
			}
		}

		if (Constant.alipay.equals(orderInfo.getPayType())){ //支付宝支付
			return getAliPaySinInfo(request,orderInfo);
		}else if (Constant.wxPay.equals(orderInfo.getPayType())){ //微信支付
			return getWxPaySinInfo(request,orderInfo);
		}else if(Constant.cmbPay.equals(orderInfo.getPayType())){ //一网通支付
			return getCmbPaySinInfo(request, orderInfo);
		}
		return null;

	}

	@Override
	public Map<String, Object> getAliPaySinInfo(HttpServletRequest request, TradeOrderInfo orderInfo) throws Exception {

		Map<String, Object> map = new HashMap<>();
		AlipayOrderInfoVo aoi = new AlipayOrderInfoVo();
		String scheme=request.getScheme();
		if("https".equals(request.getHeader("X-Forwarded-Proto"))){
			scheme=request.getHeader("X-Forwarded-Proto");
		}
		String url = scheme + "://" + request.getServerName() + request.getContextPath();
		String requestURL = request.getRequestURL().toString();
		requestURL = requestURL.substring(0, requestURL.indexOf(request.getContextPath())) + request.getContextPath();
		LOGGER.info("支付宝回调地址："+url + aoi.getNotify_url());
		aoi.setNotify_url(url + aoi.getNotify_url());
		aoi.setTimestamp(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
		AlipayBizContentVo biz_content = new AlipayBizContentVo();
		biz_content.setTotal_amount(orderInfo.getOrderMoney().toString());
		biz_content.setOut_trade_no(orderInfo.getOrderNo());
//		TradeServiceInfo serviceInfo = tradeServiceInfoService.selectByPrimaryKey(orderInfo.getServiceType());
//		biz_content.setSubject(serviceInfo.getName());
//		biz_content.setBody(serviceInfo.getDescription());
		aoi.setBiz_content(JSONObject.toJSONString(biz_content));
		Map<String, String> convertBean = BeanToMapUtil.convertBean(aoi);
		String sign = AlipaySignature.rsaSign(convertBean, AlipayConfig.PRIVATE_KEY, AlipayConfig.CHARSET);
		aoi.setSign(URLEncoder.encode(sign, AlipayConfig.CHARSET));
		map.put("aoi", aoi);
		map.put("bizContent", biz_content);
		// 支付类型
		map.put("payType", Constant.alipay);
		map.put("orderMoney", orderInfo.getOrderMoney());
		return map;
	}

	@Override
	public Map<String, Object> getWxPaySinInfo(HttpServletRequest request, TradeOrderInfo orderInfo) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		String scheme=request.getScheme();
		if("https".equals(request.getHeader("X-Forwarded-Proto"))){
			scheme=request.getHeader("X-Forwarded-Proto");
		}
		String url = scheme + "://" + request.getServerName() + request.getContextPath();
		String notifyUrl = url + WeiXinConfig.NOTIFY_URL;
		LOGGER.info("微信回调地址：" + notifyUrl);
		PrepayIdRequestHandler prepayReqHandler = new PrepayIdRequestHandler(request, null);// 获取prepayid的请求类
		String noncestr = WXUtil.getNonceStr();
		String timestamp = WXUtil.getTimeStamp();
		// 设置获取prepayid支付参数
		// 微信开放平台id
		prepayReqHandler.setParameter("appid", WeiXinConfig.APP_ID);
		// 商户号id
		prepayReqHandler.setParameter("mch_id", WeiXinConfig.PARTNER);

		// 随机字符串(少于32位)
		prepayReqHandler.setParameter("nonce_str", noncestr);
		// 商品描述
//		TradeServiceInfo serviceInfo = tradeServiceInfoService.selectByPrimaryKey(orderInfo.getServiceType());
		prepayReqHandler.setParameter("body", "好心情-" );
		// 接收微信通知的URL(微信回调url)
		prepayReqHandler.setParameter("notify_url", notifyUrl);
		// 商家订单号
		prepayReqHandler.setParameter("out_trade_no", orderInfo.getOrderNo());
		// 订单生成的机器IP，指用户浏览器端IP
		prepayReqHandler.setParameter("spbill_create_ip", request.getRemoteAddr());
		// 商品金额,以分为单位 //TODO 写死订单金额
		prepayReqHandler.setParameter("total_fee", orderInfo.getOrderMoney().intValue()*100+"");
//		prepayReqHandler.setParameter("total_fee", "1");
		// 交易类型
		prepayReqHandler.setParameter("trade_type", "APP");
		// 生成获取预支付签名
		String sign = prepayReqHandler.createSign();
		// 增加非参与签名的额外参数
		prepayReqHandler.setParameter("sign", sign);
		String gateUrl = WeiXinConfig.GATEURL;
		prepayReqHandler.setGateUrl(gateUrl);
		// 获取prepayId
		String prepayId = prepayReqHandler.sendPrepay();
		LOGGER.debug("获取prepayid------值 " + prepayId);
		// 吐回给客户端的参数
		if (null != prepayId && !"".equals(prepayId)) {
			WeiXinOrderInfoVo woi = new WeiXinOrderInfoVo();
			// 微信预支付订单id
			woi.setPrepayid(prepayId);
			woi.setNoncestr(noncestr);
			woi.setTimestamp(timestamp);
			Map<String, String> convertBean = BeanToMapUtil.convertBean(woi);
			// 生成返回到前端的sign
			String clignSign = MD5Util.md5Sign(convertBean, WeiXinConfig.PARTNER_KEY);
			woi.setSign(clignSign);
			map.put("woi", woi);
			map.put("out_trade_no", orderInfo.getOrderNo());
			// 支付类型
			map.put("payType", Constant.wxPay);
			map.put("orderMoney", orderInfo.getOrderMoney());
		}
		return map;
	}

	@Override
	public Map<String, Object> getCmbPaySinInfo(HttpServletRequest request, TradeOrderInfo orderInfo) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();

		// 线上测试
		String scheme=request.getScheme();
		if("https".equals(request.getHeader("X-Forwarded-Proto"))){
			scheme=request.getHeader("X-Forwarded-Proto");
		}
		String url = scheme + "://" + request.getServerName() + request.getContextPath();
		// 本地测试
		// String url = "http://106.38.95.114:8081/app-web";
		// 86测试
		// String url = "http://101.201.154.86:8081/app-web";

		// 支付结果通知url
		String notifyUrl = url + CmbConfig.NOTIFY_URL;
		LOGGER.info("招行回调地址：" + notifyUrl);
		// 回签url
		String rocUrl = url + CmbConfig.ROC_URL;
		// 支付完成url(APP根据这个值,进行本地跳转)
		String payEnd = url + CmbConfig.PAY_END_URL;

		CmbPrePayVo cmb = new CmbPrePayVo();

		// 订单号
		String orderNo = orderInfo.getOrderNo();
		// 一网通订单号(只能是6,10位数字,所以取系统订单的后10位,做一网通订单号)
		String billNo = SubStringUtil.subString(orderNo, 10);
		// 订单金额
		String amount = orderInfo.getOrderMoney().toString();
		// 订单日期(生成yyyymmdd格式的字符串时间)
		String date = DateUtils.formatYyyymmddNow();
		String merchantPara = "orderNo=" + orderNo;
		cmb.setBillNo(billNo);
		cmb.setAmount(amount);
		cmb.setDate(date);
		// 订单的有效期30分钟
		cmb.setExpireTimeSpan("30");

		cmb.setMerchantUrl(notifyUrl);
		cmb.setMerchantPara(merchantPara);

		// 生成merchantCode参数
		String merchantCode = getMerchantCode(date, orderInfo.getPatientId(), billNo, amount, merchantPara, notifyUrl,
				rocUrl);

		cmb.setMerchantCode(merchantCode);
		// 支付完成后,跳转到的商户地址
		String MerchantRetUrl = payEnd;
		// 医生id
		String MerchantRetPara = "doctorId=" + orderInfo.getDoctorId();

		cmb.setMerchantRetUrl(MerchantRetUrl);
		cmb.setMerchantRetPara(MerchantRetPara);

		StringBuffer buff = new StringBuffer();
		buff.append("BranchID=").append(cmb.getBranchID());
		buff.append("&CoNo=").append(cmb.getCoNo());
		buff.append("&BillNo=").append(cmb.getBillNo());
		buff.append("&Amount=").append(cmb.getAmount());
		buff.append("&Date=").append(cmb.getDate());
		buff.append("&ExpireTimeSpan=").append(cmb.getExpireTimeSpan());
		buff.append("&MerchantUrl=").append(cmb.getMerchantUrl());
		buff.append("&MerchantPara=").append(cmb.getMerchantPara());
		buff.append("&MerchantCode=").append(cmb.getMerchantCode());
		buff.append("&MerchantRetUrl=").append(cmb.getMerchantRetUrl());
		buff.append("&MerchantRetPara=").append(cmb.getMerchantRetPara());

		map.put("url", CmbConfig.PAY_URL);
		map.put("body", buff.toString());
		map.put("orderNo", orderNo);
		map.put("orderMoney", orderInfo.getOrderMoney());
		map.put("payType", Constant.cmbPay);
		LOGGER.debug("url is :" + CmbConfig.PAY_URL);
		LOGGER.debug("body is :" + buff.toString());

		LOGGER.debug("一网通请求成功");

		return map;
	}

	@SuppressWarnings("static-access")
	public static String getMerchantCode(String date, Long patientId, String billNo, String amount, String merchantPara,
			String notifyUrl, String rocUrl) {
		Map<String, String> reservedMap = new LinkedHashMap<String, String>();
		// 客户协议号
		// 用000000 + 用户id,做唯一协议号
		reservedMap.put("PNo", "000000" + patientId);
		// 交易时间
		reservedMap.put("TS", DateUtils.foramtFullDateNow());
		// 协议商户企业编号
		reservedMap.put("MchNo", CmbConfig.NTBNBR);

		// 以下字段“签约+支付”时必填：
		// 协议开通请求流水号
		reservedMap.put("Seq", IdentityHelper.SerializeNo(15));
		// 协议开通结果通知命令请求地址
		reservedMap.put("URL", rocUrl);

		// 以下字段选填：
		// 协议开通结果通知命令参数
		reservedMap.put("Para", "");
		// 协议用户ID
		reservedMap.put("MUID", "");
		// 协议手机号
		reservedMap.put("Mobile", "");
		// 地理位置
		reservedMap.put("LBS", "");
		// 客户风险等级
		reservedMap.put("RskLvl", "");

		String reserved = XMLUtil.cmbMapToXml(reservedMap);

		MerchantCode mc = new MerchantCode();
		String merchantCode = mc.genMerchantCode(CmbConfig.SECRET_KEY, date, CmbConfig.BRANCH_ID, CmbConfig.CO_NO,
				billNo, amount, merchantPara, notifyUrl, "", "", "", "", reserved);

		return merchantCode;
	}

	@Override
	public TradeOrderInfo getPatientNoPayOrder(Long patientId, Long doctorId,Integer serviceType) {
		Map<String, Object> map = new ConcurrentHashMap<String, Object>();
		map.put("doctorId", doctorId);
		map.put("patientId", patientId);
		map.put("serviceId", serviceType);
		return tradeOrderInfoDao.get("getPatientNoPayOrderByServiceId", map);
	}

	@Override
	public boolean getPatientNoPayOrderByServiId(Long doctorId, Long patientId, Integer serviceType) {
		Map<String, Object> map = new ConcurrentHashMap<String, Object>();
		map.put("doctorId", doctorId);
		map.put("patientId", patientId);
		map.put("serviceId", serviceType);
		TradeOrderInfo tradeOrderInfo = tradeOrderInfoDao.get("getPatientNoPayOrderByServiceId", map);
		return tradeOrderInfo == null ? false : true;
	}

	@Override
	public boolean getPatientValidOrderByServiId(Long doctorId, Long patientId, Integer serviceType) {
		Map<String, Object> map = new ConcurrentHashMap<String, Object>();
		map.put("doctorId", doctorId);
		map.put("patientId", patientId);
		map.put("serviceId", serviceType);
		int flag = tradeOrderInfoDao.get("getPatientValidOrderByServiId",map);
		return flag > 0 ? true : false;

	}

	@Override
	public boolean findUntreatedOrderOrderByDocId(Long doctorId) {
		int untreatedCount = tradeOrderInfoDao.get("findUntreatedOrderOrderByDocId", doctorId);
		return untreatedCount > 0 ? true : false;
	}

	@Override
	public Map<String, Object> procTradeOrderPayment(String orderNo, HttpServletRequest request, String payType)
			throws Exception {
		TradeOrderInfo orderInfo = tradeOrderInfoDao.get("selectByPrimaryKey", orderNo);
		if (Constant.alipay.equals(payType)) { // 支付宝支付
			return getAliPaySinInfo(request, orderInfo);
		} else if (Constant.wxPay.equals(payType)) { // 微信支付
			return getWxPaySinInfo(request, orderInfo);
		} else if (Constant.cmbPay.equals(payType)) {// 一网通支付
			return getCmbPaySinInfo(request, orderInfo);
		}
		return null;
	}

	@Override
	public void deleteOrder(String orderNo) throws Exception {
		tradeOrderInfoDao.updateByObject("deleteOrder", orderNo);
	}

	@Override
	public void procCancelOrder(String orderNo, String cancelMark) throws Exception {
		Map<String, Object> map = new ConcurrentHashMap<String, Object>();
		map.put("orderNo", orderNo);
		map.put("cancelMark", cancelMark);
		tradeOrderInfoDao.update("procCancelOrder", map);
	}

	@Override
	public List<TradeOrderInfo> getPatientNoPayOrderList(Long patientId) {
		return tradeOrderInfoDao.find("getPatientNoPayOrderList", patientId);
	}

	@Override
	public int getBuyNumberByDocIdAndSerId(Long doctorId, Integer serviceId) {
		Map<String, Object> map = new ConcurrentHashMap<String, Object>();
		map.put("doctorId", doctorId);
		map.put("serviceId", serviceId);
		return tradeOrderInfoDao.find("getBuyNumberByDocIdAndSerId", map).size();
	}

	@Override
	public TradeOrderInfo getPatientIsBuyTheDocSer(Integer serviceId, String doctorId, Long patientId) {
		Map<String, Object> map = new ConcurrentHashMap<String, Object>();
		map.put("doctorId", doctorId);
		map.put("serviceId", serviceId);
		map.put("patientId", patientId);
		return tradeOrderInfoDao.get("getPatientIsBuyTheDocSer", map);
	}

	/**
	 * 修改完成订单状态(订单完成)
	 * 
	 * @throws Exception
	 */
	public void updateCompleteOrderStatusAndEndTime() throws Exception {
		// 将下单时间超过24小时(后台设置的时间),并且医生发言数超过1条的订单数据,将订单状态改为已完成
		List<TradeOrderInfoDto> tradeOrderList = getCompleteOrderList();
		if (!CollectionUtils.isEmpty(tradeOrderList)) {

			for (TradeOrderInfoDto tradeOrder : tradeOrderList) {
				// 将订单状态改成已完成
				tradeOrder.setStatus(TradeOrderInfoStatus.ORDER_COMPLETE.getValue());
				// 修改订单的结束时间
				tradeOrder.setEndTime(DateUtil.getDate());
				tradeOrderInfoDao.update("updateByPrimaryKeySelective", tradeOrder);
			}
		}
	}

	/*	*//**
			 * 得到时间间隔
			 * 
			 * @return
			 *//*
			 * public Integer getDateInterval(){ return
			 * BaseDataInitialize.getOrderDateInterval(); }
			 */

	@Override
	public TradeOrderInfo selectByorderNo(String orderNo) {
		return tradeOrderInfoDao.get("selectByPrimaryKey", orderNo);
	}

	@Override
	public int updateByPrimaryKeySelective(TradeOrderInfo tradeOrderInfo) {
		return tradeOrderInfoDao.update("updateByPrimaryKeySelective", tradeOrderInfo);
	}

	@Override
	public List<TradeOrderInfoDto> getTradeOrderInfoList(TradeOrderInfoVo tradeOrderInfoVo) {
		return tradeOrderInfoDao.find("getTradeOrderInfoList", tradeOrderInfoVo);
	}

	@Override
	public TradeOrderInfoDto getOrderInfoByPidAndDid(Long doctorId, Long patientId) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("doctorId", doctorId);
		map.put("patientId", patientId);
		return tradeOrderInfoDao.get("getOrderInfoByPidAndDid", map);
	}

	@Override
	public TradeOrderInfoDto getOrderInfoByDIdAndPIdAndSerId(Long doctorId, Long patientId, Integer serviceType) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("doctorId", doctorId);
		map.put("patientId", patientId);
		map.put("serviceType", serviceType);
		return tradeOrderInfoDao.get("getOrderInfoByDIdAndPIdAndSerId", map);
	}

	@Override
	public void insert(TradeOrderInfo orderInfo) {
		tradeOrderInfoDao.insert(orderInfo);
	}

	@Override
	public List<TradeOrderInfoDto> getOrderFormChartList() {
		return tradeOrderInfoDao.find("getOrderFormChartList", null);
	}

	@Override
	public List<TradeOrderInfo> findOrderFormChartWeeksData() {
		return tradeOrderInfoDao.find("findOrderFormChartWeeksData", null);
	}

	@Override
	public List<TradeOrderInfoDto> findOrderFormChartMonthsList() {
		return tradeOrderInfoDao.find("findOrderFormChartMonthsList", null);
	}

	@Override
	public List<PatientTradeOrderDto> findTradeOrderInfoByPatientId(String orderType, Long patientId) {
		Map<String, Object> map = new ConcurrentHashMap<String, Object>();
		if ("underwayOrder".equals(orderType)) {
			map.put("paidStatus", 1);
			map.put("haveOrderStatus", 2);
		} else if ("nonPaymentOrder".equals(orderType)) {
			map.put("nonPaymentStatus", 0);
		}
		map.put("patientId", patientId);
		map.put("orderType", orderType);
		return tradeOrderInfoDao.find("findTradeOrderInfoByPatientId", map);
	}

	@Override
	public PatientTradeOrderDto findTradeOrderInfoDetail(String orderNo, Integer serviceId) {
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("orderNo", orderNo);
		map.put("serviceId", serviceId);
		return tradeOrderInfoDao.get("findTradeOrderInfoDetail", map);
	}



	@Override
	public void updateInstitutionOrdersUnDetermined() throws Exception {
		// 下单时间超过2小时,机构未确认,自动退款
		List<TradeOrderInfo> tradeOrderList = getInstitutionOrdersRefundList();
		if (!CollectionUtils.isEmpty(tradeOrderList)) {

			for (TradeOrderInfo tradeOrder : tradeOrderList) {
				// 修改订单的状态
				if (tradeOrder.getOrderMoney().compareTo(new BigDecimal(0)) == 0) {
					tradeOrder.setStatus(TradeOrderInfoStatus.ORDER_COMPLETE_REFUND.getValue());
					tradeOrder.setEndTime(new Date());
					tradeOrder.setRefundTime(new Date());
				} else {
					String payType = tradeOrder.getPayType();
					//退款返回接口返回的字符串
					String refund = "";
					if(!StringUtil.isEmpty(payType)){ //支付类型不是空
						if (payType.equals(Constant.alipay)) {//判断支付类型pay_type--支付宝 
							  refund = alipayService.refundRequest(tradeOrder);
						}else if(payType.equals(Constant.wxPay)){ //微信退款
							 refund = weiXinService.refundRequest(tradeOrder);
						
						}else if(payType.equals(Constant.cmbPay)){ //一网通退款
							 refund = cmbpayService.refundRequest(tradeOrder);
						}
					}
					//退款成功
					if(refund.equals("success")){
						//退款成功,将订单号从redis移除
						JedisManager.del(tradeOrder.getOrderNo());
						//修改订单的状态
						tradeOrder.setStatus(TradeOrderInfoStatus.ORDER_COMPLETE_REFUND.getValue());
						tradeOrder.setRefundTime(DateUtils.getDate());
						tradeOrder.setEndTime(DateUtil.getDate());
						tradeOrder.setRefundReason("机构未确认订单");
					}else{
						tradeOrder.setRefundReason("机构未确认订单");
						tradeOrder.setStatus(TradeOrderInfoStatus.ORDER_STAY_REFUND.getValue());
					}
				}
				tradeOrderInfoDao.update("updateByPrimaryKeySelective", tradeOrder);
			}
		}
	}

	@Override
	public void updateInstitutionOrderStatus() throws Exception {
		List<TradeOrderInfoDto> tradeOrderList = getInstitutionOrdersBookedList();
		if (!CollectionUtils.isEmpty(tradeOrderList)) {

			for (TradeOrderInfoDto tradeOrder : tradeOrderList) {
				// 将订单状态改成已入库
				tradeOrder.setStatus(TradeOrderInfoStatus.ORDER_RECORDING.getValue());
				tradeOrder.setRecordTime(new Date());
				tradeOrderInfoDao.update("updateByPrimaryKeySelective", tradeOrder);
				// 状态修改成功,将订单号从redis移除
				JedisManager.del(tradeOrder.getOrderNo());
			}
		}
	}

	@Override
	public List<TradeOrderInfo> getInstitutionOrdersRefundList() {
		return tradeOrderInfoDao.find("getInstitutionOrdersRefundList", Constant.INSTITUTION_REFUNDING_DATE);
	}

	@Override
	public List<TradeOrderInfoDto> getInstitutionOrdersBookedList() throws Exception {
		return tradeOrderInfoDao.find("getInstitutionOrdersBookedList", Constant.INSTITUTION_BOOKED_DATE);
	}

	@Override
	public int getPayOrderCount() {
		return tradeOrderInfoDao.get("getPayOrderCount", null);
	}


	
	

	@Override
	public int getPayOrderNumber(Map<String,String> map){
		return tradeOrderInfoDao.get("getPayOrderNumber",map);
	}
	
	

	@Override
	public int getActiveDoctorNumber(String date){
		return tradeOrderInfoDao.get("getActiveDoctorNumber",date);
	}
	
	
	
	@Override
	public int getPayActiveDoctorNumber(String date){
		return tradeOrderInfoDao.get("getPayActiveDoctorNumber",date);
	}
	
	
	@Override
	public int getFreeActiveDoctorNumber(String date){
		return tradeOrderInfoDao.get("getFreeActiveDoctorNumber",date);
	}
	

	@Override
	public BigDecimal getOrderMoneyByPayTime(String date){
		return tradeOrderInfoDao.get("getOrderMoneyByPayTime",date);
	}

	@Override
	public TradeOrderInfo selectUnPayText(Long patientId, Long doctorId) {
		// TODO Auto-generated method stub
		Map<String, Object> map = new HashMap<>();
		map.put("patientId", patientId);
		map.put("doctorId", doctorId);
		return tradeOrderInfoDao.get("selectUnPayText");
	}

	@Override
	public List<TradeInComeDto> getIncomeDetailList(Long docId, Integer serviceType) {
		List<TradeInComeDto> list=new LinkedList<TradeInComeDto>();
		List<TradeInComeDto> dtoList=null;
		if(serviceType!=10000){
			Map<String,Object> map=new HashMap<String,Object>();
			map.put("docId",docId);
			map.put("serviceType",serviceType);
			dtoList=tradeOrderInfoDao.find("getOrderIncomeList", map);
		}else
		{
			dtoList=tradeOrderInfoDao.find("getActiveIncomeList", docId);
		}
		Set<String> set=new HashSet<String>();
		for(int i=0;i<dtoList.size();i++){
			TradeInComeDto dto=dtoList.get(i);
			Date d=dto.getInComeTime();
			String date=DateUtils.formatDate(d);
			String yyyy_mm=date.substring(0, 7);
			//是否是本月
			boolean bo=DateUtils.isThisTime(d,"yyyy-MM");
			if(bo){
				dto.setMonth("本月");
			}else
			{
				dto.setMonth(yyyy_mm);
			}
			if(!set.contains(yyyy_mm)){
				set.add(yyyy_mm);
				dto.setFlag(true);
			}
		    list.add(dto);
		}
		return list;
	}

	@Override
	public List<TradeInComeDto> getIncomeDetailTotal(Long docId) {
		List<TradeInComeDto> list=null;
		list= tradeOrderInfoDao.find("getOrderIncomeTotal", docId);
		if(list==null){
			list=new ArrayList<TradeInComeDto>();
		}
		TradeInComeDto tradeInComeDto= tradeOrderInfoDao.get("getActiveIncomeTotal", docId);
		list.add(tradeInComeDto);
	    return list;
	}

	
}
